import { apiAsyncAuth } from '@/http/api/login';
import { eLocalStorageConfig } from '@/interface/elocal_storage';
import { eMenuType } from '@/interface/enum';
import { iRouteInfo } from '@/interface/iRouteInfo';
import { AsyncRoute } from '@/router/main';
import { useMenus } from '@/store/menus';
import LogUtils from 'panda-log';
import { RouteMeta, Router, RouteRecordRaw } from 'vue-router';
import { getSessionStorage } from './utils';

// 同步路由
export const syncRoute = (authRoute: iRouteInfo[], localRoute: RouteRecordRaw[]): RouteRecordRaw[] => {
  const tempRoutes: { [key: string]: RouteRecordRaw } = {};
  authRoute.forEach(route => {
    handleRoute(route, localRoute, tempRoutes);
  });
  const arrs = convertRouteArray(tempRoutes, localRoute);
  const depositRoutes: RouteRecordRaw[] = [];
  // 组装路由
  assembleRoute(arrs, depositRoutes);
  redirctRoute(depositRoutes);
  depositRoutes.sort((a, b) => (a.meta as any).sort - (b.meta as any).sort);
  return depositRoutes;
};

export const addRoutes = (router: Router, routes: RouteRecordRaw[]) => {
  //   const router = useRouter();
  const rs = router.getRoutes();
  const main = rs.find(r => r.path === '/');
  if (main) {
    router.removeRoute('main_container');
    main.children = routes.sort((a, b) => {
      const meta1 = a.meta;
      const meta2 = b.meta;
      if (meta1 && meta2) {
        return (meta1.sort as number) - (meta2.sort as number);
      } else if (!meta1) {
        return -1;
      }
      return 1;
    });
    router.addRoute(main);
  }

  //   for (let index = 0; index < routes.length; index++) {
  //     const element = routes[index];
  //     router.addRoute(element);
  //   }
};

const assembleRoute = (arrs: RouteRecordRaw[], depositRoutes: RouteRecordRaw[]): RouteRecordRaw[] => {
  const tmpArrs = assembleTopRoute(arrs, depositRoutes);
  const t = assemblePageRoute(tmpArrs, depositRoutes);
  return t;
};
const assemblePageRoute = (arrs: RouteRecordRaw[], depositRoutes: RouteRecordRaw[]): RouteRecordRaw[] => {
  let tmpArrs = [...arrs];
  const d = [...depositRoutes];
  tmpArrs.forEach(t => {
    const result = t.meta && t.meta.menu_type === eMenuType.PAGE;

    if (result) {
      // 在组装的路由数组里查找该路由
      const parentPath = t.meta ? t.meta.parentPath : '';

      if (parentPath) {
        const parentRoute = findRoute(parentPath as string, d);

        if (parentRoute) {
          // 查找子页面是否在父级菜单里
          const childRoute = findRoute(t.path, parentRoute.children || []);
          if (!childRoute) {
            if (parentRoute.children) {
              parentRoute.children.push(t);
            } else {
              parentRoute.children = [t];
            }
          }
          // } else {
          //   // 需要将父级菜单添加进菜单里
          //   // 首先要要找父级菜单
          //   const parent = findRoute(parentPath as string, depositRoutes);
        }
      } else {
        d.push(t);
      }
    }
    return !result;
  });
  return d;
};
const assembleTopRoute = (arrs: RouteRecordRaw[], depositRoutes: RouteRecordRaw[]): RouteRecordRaw[] => {
  let tmpArrs = [...arrs];
  //    const info : RouteRecordRaw = {}
  tmpArrs = tmpArrs.filter(t => {
    const result = t.meta && t.meta.menu_type === eMenuType.MENU;
    if (result) {
      // 在组装的路由数组里查找该路由
      const depositRoute = findRoute(t.path, depositRoutes);
      if (!depositRoute) {
        depositRoutes.push(t);
      }
    }
    return !result;
  });
  return tmpArrs;
};

export const findRoute = (targetPath: string, depositRoutes: RouteRecordRaw[]): RouteRecordRaw | null => {
  if (!targetPath) return null;
  for (let index = 0; index < depositRoutes.length; index++) {
    const element = depositRoutes[index];
    if (element.path === targetPath) {
      return element;
    } else if (element.children && element.children.length > 0) {
      const ch = findRoute(targetPath, element.children);
      if (ch) {
        return ch;
      }
    }
  }
  return null;
};

export const findWholeRouteByPath = (targetPath: string, depositRoutes: RouteRecordRaw[]): RouteRecordRaw | null => {
  for (let index = 0; index < depositRoutes.length; index++) {
    const element = depositRoutes[index];
    let path = element.path;
    if (!path.startsWith('/') && element.meta) {
      path = element.meta!.parentPath + '/' + path;
    }
    if (path === targetPath) {
      return element;
    } else if (element.children && element.children.length > 0) {
      const result = findWholeRouteByPath(targetPath, element.children);
      if (result) {
        return element;
      }
    }
  }
  return null;
};

const convertRouteArray = (routes: { [key: string]: RouteRecordRaw }, localRoute: RouteRecordRaw[]): RouteRecordRaw[] => {
  const arrs: RouteRecordRaw[] = [];
  for (const key in routes) {
    if (Object.prototype.hasOwnProperty.call(routes, key)) {
      const element = routes[key];
      arrs.push(element);
    }
  }
  // 因为如果是多级菜单，存在只选择了多级的部分菜单，会导致父级的path未被选中，所以需要将父级找到
  for (let index = 0; index < arrs.length; index++) {
    const element = arrs[index];
    if (element.meta as any) {
      const parentPath = (element.meta as any).parentPath;
      const info = routes[parentPath];
      if (!info) {
        let pRoute = findRoute(parentPath, localRoute);
        if (pRoute) {
          pRoute = {
            ...pRoute,
            children: [],
          };
          // 不要重复添加
          const result = arrs.find(a => a.path === pRoute?.path);
          if (!result) {
            arrs.push(pRoute);
          }
        }
      }
    }
  }
  return arrs;
};

const handleRoute = (route: iRouteInfo, localRoute: RouteRecordRaw[], tempRoutes: { [key: string]: RouteRecordRaw }) => {
  for (let index = 0; index < localRoute.length; index++) {
    const lRoute = localRoute[index];
    const tRoute = tempRoutes[route.path];
    if (!tRoute) {
      if (route.path === lRoute.path) {
        tempRoutes[route.path] = {
          ...lRoute,
          path: route.path,
          meta: route.meta as RouteMeta,
          name: route.name,
          children: [],
        };
      } else if (lRoute.children && lRoute.children.length) {
        handleRoute(route, lRoute.children, tempRoutes);
      }
    }
  }
};
export const getAuthRoute = async (router: Router): Promise<RouteRecordRaw[]> => {
  try {
    let depositRoutes: RouteRecordRaw[] = [];
    // let routes = getSessionStorage<iRouteInfo[], []>(eLocalStorageConfig.ROUTES, []);
    depositRoutes = useMenus().asyncRoutes;
    console.log('depositRoute', depositRoutes);

    if (depositRoutes.length === 0) {
      const res = await apiAsyncAuth();
      if (res.data) {
        depositRoutes = syncRoute(res.data, AsyncRoute);
      }
      LogUtils.debug('depositRoute:', depositRoutes);
      useMenus().asyncRoutes = depositRoutes;
    }
    LogUtils.info(depositRoutes);
    // useMenus().asyncRoutes = depositRoutes;
    addRoutes(router, depositRoutes);
    // 获取路由
    const url = getSessionStorage<string, string>(eLocalStorageConfig.PRE_URL, '');
    if (url) {
      const info = findRoute(url, depositRoutes);
      if (info) {
        router.push(url);
      }
    } else {
      LogUtils.info('添加完了路由，准备强制转换到第一个权限页面');
      if (depositRoutes.length > 0) {
        router.push(depositRoutes[0].path);
      }
    }

    return depositRoutes;
  } catch (error) {
    console.log('error:', error);
    return [];
  }
};

/**
 * 获取到最顶层路由对象
 * @param url
 * @param routes
 */
export const findTopRoute = (url: string, routes: Array<RouteRecordRaw>, parentRoute: Array<RouteRecordRaw>, topRoute?: RouteRecordRaw) => {
  for (let index = 0; index < routes.length; index++) {
    const element = routes[index];
    if (element.path === url) {
      parentRoute.push(topRoute || element);
    } else if (element.children && element.children.length > 0) {
      findTopRoute(url, element.children, parentRoute, element);
    }
  }
  // return null;
};

function redirctRoute(routes: RouteRecordRaw[]) {
  routes.forEach(route => {
    if (route.children && route.children.length > 0) {
      if (route.redirect) {
        const info = findRoute(route.redirect.toString(), route.children);
        if (!info) {
          route.redirect = route.children[0].path;
        }
      }
    }
  });
}

/**
 * 将树状路由给扁平化
 * @param route
 * @param cRoute
 * @returns
 */
export const flatRouteInfo = (route: RouteRecordRaw[], cRoute: iRouteInfo[]): iRouteInfo[] => {
  for (let index = 0; index < route.length; index++) {
    const element = route[index];
    const find = cRoute.find(c => c.path === element.path);
    if (find) continue;
    const info: iRouteInfo = {
      name: element.name || '',
      path: element.path,
      meta: element.meta as any,
    };
    cRoute.push(info);
    if (element.children) {
      const syncRoute = flatRouteInfo(element.children, []);
      cRoute.push(...syncRoute);
    }
  }
  return cRoute;
};
